Conformance Testing in OLE DB 2.0

This paper has four sections:

Introduction

The purpose of the conformance tests is to encourage developers to write good, compliant OLE DB providers.

The conformance tests help provider writers confirm that their implementations match the OLE DB specification. Having a common set of tests also encourages consistent behavior across providers.

Comprehensive testing of any OLE DB provider includes many tasks:

The conformance tests contribute to the first task (OLE DB interface testing) and to the last task (consumer testing, through ADO). They are not intended to address any other tasks in this list.

The conformance tests are meant to supplement a provider writer’s own testing, not to replace it.

They include test variations for normal usage, as well as some error and boundary cases. They do not check performance, stress scenarios, low-resource conditions, multiuser cases, or provider-specific behavior.

The conformance tests check usage of individual OLE DB interfaces and ADO methods. They do not check application scenarios.

There are three stages in the life cycle of conformance tests: unsupported, proposed, and approved.

Unsupported tests are provided only as examples. They were originally designed to work with the OLE DB Provider for ODBC Drivers, and may not work correctly with other providers.

Proposed tests have been updated to work with a wide range of providers — for example, read-write, read-only, SQL, and non-SQL. After broader exposure, they will move to “approved” category. Microsoft  plans to provide web links for providers who pass the approved tests. Other incentives may be used in the future. They are made available now so provider teams can use them to test their providers.

Two sets of conformance tests are included in the Data Access SDK version 2.0: OLE DB interface tests and ADO minimal tests.

The OLE DB interface tests check compliance to standards in the OLE DB Programmer’s Reference. There is at least one test module per OLE DB interface. The tests are grouped into levels, corresponding to the OLE DB interface levels.

OLE DB leveling identifies the critical interfaces and behaviors (properties) required for providers and expected by consumers. If you are unfamiliar with OLE DB leveling, see OLE DB Leveling in this collection of technical articles.

The OLE DB interface tests were originally written to test theMicrosoft OLE DB Provider for ODBC Drivers, which is also included in this SDK. The first set of tests (for the level 0/minimum provider interfaces) has been modified to handle a wide range of providers, and has been moved from Unsupported to Proposed.

In Data Access SDK version 2.0, only the level 0 (minimum) interface tests are supported. Tests for the other interfaces are still available in the Unsupported subdirectory. In future releases, more interface tests will be improved to support generic providers, and will be moved from Unsupported to Proposed.

The ADO minimal tests are a small set of tests, at least one per ADO method, which check that ADO statements work correctly against a provider. These tests act as a “sanity” check that ADO applications should work with that provider. There are tests for each ADO method, including methods used for updates and for transactions. The tests are grouped so that you can run just the level 0 tests, which do not require updatability or transactions; or you can run the full set of ADO tests.

Both the OLE DB and ADO tests use Table Dump generated files to identify provider-specific information, and to handle provider variations (such as read-only versus read-write, SQL versus non-SQL). The TableDump utility generates initialization files needed by the tests. This utility can be found in the Tools subdirectory.

Conformance directory structure:

Conformance

Include

Lib

Tests

     Proposed

     Unsupported

Tools

     ADOPriv

     PrivLib

     TableDump

Section 2: Building and Running the OLE DB Conformance Tests

OLE DB Level 0 Conformance Tests

There is at least one level 0 test module for each level 0 interface, plus one test module for Data Coercion, and one test module for simple threading cases. In total there are 19 level 0 tests. The names of these tests are abbreviated forms of the interface names.

Name of file Interface tested
IACCESSR IAccessor
ICLSFACT IClassFactory and CoCreateInstance
ICOLINFO IColumnsInfo
ICNVTTYP IConvertType
IDBCRSES IDBCreateSession
IDBINIT IDBInitialize
IDBPRPTS IDBProperties
IGETDSO IGetDataSource
IOPENRW IOpenRowset
IPERSIST IPersistFile
IROWSET IRowset
IROWCHNG IRowsetChange
IROWDEL IRowsetChange::DeleteRows
IROWIDEN IRowsetIdentity
IROWINFO IRowsetInfo
IROWNEW IRowsetChange::InsertRow
ISESPRPT ISessionProperties
THREADS Threading test (tests free-threaded only, not apartment model)
DATALITE Data Coercion test

Test Coverage

The level 0 test modules cover each interface in the minimum provider level section of the OLE DB Leveling document, plus Data Coercion and Threading.

The tests are organized into test modules (one per interface). Each test module contains test cases, and each test case contains test variations.

All the OLE DB test modules use Privlib.lib, which is a set of common C++ functions such as table creation, data comparison, and accessor creation.

Getting Started

The OLE DB test sources, include files, and resource files can be found in

InstallDirectory\Conformance\Tests\Proposed\OLEDBTests

Additional include files are in

InstallDirectory\Conformance\Include

Libs are in

InstallDirectory\Conformance\Lib

Source for the test tools (PrivLib and TableDump) can be found in

InstallDirectory\Conformance\Tools\

Local Test Manager (LTM), the tool used to run the conformance tests, can be found in

InstallDirectory\bin\oledb

Building a Tool (TableDump or Privlib) or Test

You should build PrivLib and TableDump before trying to build any of the OLE DB tests.

To build a tool or test, use Open Workspace on the .dsp in Visual C++®.

For PrivLib, the .dsp is in

InstallDirectory\Conformance\Tools\PrivLib

Add all the include directories and all the LIB directories for the version 2.0 SDK to your Visual C++ directory. (To do this in Visual C++, on the Tools menu, click Options, and then click Directories.)

Update your system path to include the following directories at the beginning of the path list:

InstallDirectory\Conformance\Tests\Proposed\OLEDBTests\Include

InstallDirectory\Conformance\Include

InstallDirectory\Include

InstallDirectory\Conformance\Lib

For VC 5 users, build PrivLib using the default target.

For VC 6 users, change the default target to "privlib - Win32 x86 Debug" or "privlib - Win32 (Alpha) axp Debug", and then build.

To build an OLE DB test on an Intel® machine, build the test using the Debug MBCS target. On an Alpha machine, build the tests with the DEBUG target. For VC 5 users, these targets should be the default targets. For VC 6 users, change the default targets, and then build.

Create an initialization file by using the TableDump program found in the Tools directory. (See Section 3 of this paper for more information on the TableDump utility.)

Running the OLE DB Conformance Tests

The Local Test Manager (LTM) is now a standalone exe that does not have to be registered. Once LTM is running, set up your provider by adding a new provider, which means specifying the connection string. The next section contains more information on creating a provider connection string.

Register the tests by going to Test/Register Item and selecting the Test module to register.

Next, click the test module (not just so the test module name is highlighted but the box is checked), click the provider you added, and then click Run.

Test modules and LTM are organized so you can run a test module, a test case, or a test variation. Hightlight the test module name and click the plus sign next to the test module to expose the test cases in that module. Click the plus sign next to a test case to expose the test variations in that test case. Each variation tests a single test scenario. Each variation returns pass, failure, or skipped. Many variations also return the expected HRESULT and the actual HRESULT received if an error occurs.

Provider Connection String

Before running a test in LTM, you must set up a provider and specify a provider connection string. Normally, you should use an initialization file (FILE=filename.out) and specify the connection flags:

CONFLEVEL=CONF_LEVEL_0 | CONF_STRICT;

where

CONFLEVEL=CONF_LEVEL_0 specifies that all level 0 interfaces are supported.

CONFLEVEL=CONF_STRICT specifies that only level 0 interfaces are used when running the tests.

Sample provider strings

Provider: OLE DB Provider for ODBC Drivers

LTM connection string:

DATASOURCE=datasource; USERID=userid; PASSWORD=password;

DATASOURCE identifies the ODBC data source name set up through the ODBC Data Source Administrator.

Provider: SQL Server OLE DB Provider

LTM connection string:

DATASOURCE=server; USERID=userid; PASSWORD=password;

DATASOURCE identifies the name of the server to which you’re connecting.

Provider: Oracle OLE DB Provider

LTM connection string:

DATASOURCE=server; USERID=userid; PASSWORD=password;

DATASOURCE identifies the name of the Oracle server to which you’re connecting.

Provider: OLE DB Simple Provider (OSP)

LTM connection string:

FILE=\filename.ini;

This is normally run with an .ini file because OSP does not support commands.

Provider: Jolt (OLE DB Provider for Microsoft® Jet)

LTM connection string:

DATASOURCE=c:\file.mdb; USERID=Admin;

Debugging a Test

The level 0 tests should run with zero failures.

However, in case of a failure, you can debug by following these steps:

  1. In Visual C++, open any of the test project files in \Msdasdk\Comformance\Tests\Proposed.

  2. On the Settings menu, click Project, and then click the General tab.

  3. Under Executable for debug session, enter the path to LTM.exe, for example:

    c:\msdasdk\bin\oledb\ltm.exe

  4. Open the source code for the test in the Src directory, then set breakpoints.

  5. To start LTM.exe, press F5.

  6. Select the test variations to debug, select the provider, and then start the test.

    You will hit your breakpoint.

Note   If you did not build the test DLL, then the .pdb file must be in the same directory as the test, or in a search path.

Section 3: Using the Table Dump Utility to Generate .Ini Files

Trying to develop complete OLE DB conformance tests generic enough to handle the broad range of OLE DB providers is not an easy task. There are many differences, limitations, and issues that are unique to each and every provider.

Some of the major issues are:

Just trying to initialize generically to a provider is not trivial. We need more information from the provider. To guarantee data is sent and received correctly we have to know what the data is supposed to be ahead of time. With a provider that doesn’t support Table Creation or modification of data, it’s hard to establish a known set of data.

To solve these problems and still test a wide range of OLE DB providers, we have developed an initialization file that can be used by all conformance tests. This file contains all necessary information to get initialized to the provider, understand the provider’s command syntax if available, confirm that the data retrieved is correct, and verify all other aspects of the provider meeting a particular conformance level.

TableDump creates and obtains all information needed to run for the provider’s level of conformance.

Provider Requirements

To solve the stated problems and still work with the broad range of providers, we currently impose the following requirements.

Data Requirements

For complete conformance testing there are requirements placed upon the table/data provided to the conformance tests:

Usage

TableDump is a simple command-line utility that takes arguments for all the required information it needs.

Here is a list of current arguments, their values, and meaning.

Note   All arguments are uppercase. They must be followed by “=” and end in a semicolon to distinguish them from other arguments.

PROVIDER=ProviderName;

Required Argument. This is the Provider ProgID of the provider to use. TableDump will use ProgIDToCLSID to convert this to a CLSID to obtain an instance of the provider in CoCreateInstance.

TABLENAME=TableName;

Required Argument. This is the TableName to pass to IOpenRowset.

Note   Although the argument is called TableName, this does not imply that TableDump only works with relational providers. Here, TableName just indicates the DBID passed to IOpenRowset.

BINDINGTYPE=DBTYPE_WSTR | DBTYPE_STR | DBTYPE_VARIANT;

Optional Argument. Normally this option is not needed. When TableDump creates the Accessor, it needs to bind all columns to a type that can be represented in a file (string format). Because all providers are required to convert all supported types to DBTYPE_WSTR, this should not be needed by a provider that conforms to the spec, since this is the default TableDump will use. Unfortunately, not all providers conform, so we have allowed the user to specify the binding type to a common type that can be converted to STR. If using DBTYPE_VARIANT, it’s the provider’s responsibility to convert all values to VARIANT, and the tool will handle all conversions from VARIANT to string.

DEFAULTQUERY=DefaultQuery; 

Optional Argument. Normally this option is not needed. If you want to test command support, this is the default command for all queries used by the tests and PrivLib. All entries in the QUERY section will have this command as the default. You can then modify that section based upon the grammar or command syntax required for your provider.

OUTPUT=OutputFileName; 

Optional Argument. This is the output file name for the generated .ini file. You can include the entire path, including file name and extension. TableDump will use whatever is provided, or will default to “TableDump.out” if this option is not specified.

CACHE_AUTHINFO=;

ENCRYPT_PASSWORD=;

INTEGRATED=;    

MASK_PASSWRD=;

PASSWORD=;      

PERSIST_ENCRYPTED=;

PERSIST_SENSITIVE_AUTHUNFO=;

USERID=;

DATASOURCE=;

HWND=;          

IMPERSONATION_LEVEL=;

LCID=;          

LOCATION=;     

MODE=;         

PROMPT=;       

PROTECTION_LEVEL=;    

PROVIDERSTRING=;     

TIMEOUT=;        

Optional Arguments. Each one of the above arguments corresponds to a property in the DBPROPSET_DBINIT group (without the preceding DBPROP_*_). To initialize your provider, you need to specify only whatever arguments are required. If none are needed for initialization, then none need to be specified. When using MSDASQL, usually only DATASOURCE, USERID, and PASSWORD are needed to initialize the provider.

Usage With LTM

When creating a provider, specify FILE=filename.ini in the LTM InitString (). When running a test, the test will check the existence of this keyword and will process the .ini file before beginning any test variations.

Format

Currently the format of the .ini is not that important because there is a tool generator. For most providers, the file will not have to be modified. In case manual editing is required, the following gives a brief description of the .ini file’s sections and meanings, along with a sample .ini file.

[INFO:]

This is for all provider initialization and other init information. Currently this will contain:

The following sample is from a provider MSDASQL, the table is Customers, and the initialization properties are DBPROP_INIT_DATASOURCE, DBPROP_AUTH_PASSWORD, and DBPROP_AUTH_USERID:

[INFO] {Provider (Table, <DataSource>, <DefaultQuery>)}
{ PROVIDER=MSDASQL (TABLE=Customers, DATASOURCE= OLE_DB_NWind_Jet}

[QUERY:]

This section is a large list of all the command statements that the test will try to use in the process of testing the provider. TableDump will generate all of these based upon the specified default query when the tool is used. This section may need to be manually edited to make sure that all command statements contain the correct grammar, columns, etc. to obtain the operation. The uppercase enumeration indicates the intended command, and everything between quotes represents the provider-specific syntax of that operation.

This section is only looked at if you’re using the DEFAULTQUERY option (see the option for more details). If the above example specified DEFAULTQUERY=select * from Customers, this section would contain all statements with a default CommandText string within the quotes.

The first SELECT_ALLFROMTABLE represents a command that will get executed to select all the columns from the table, so “select * from Customers” is our provider’s syntax to do that. The next is SELECT_EMPTYROWSET and the text inside quotes is the provider-specific syntax to obtain an empty rowset.

 [QUERY] {SQLEnumIdentifier("Query")}
{SELECT_ALLFROMTBL("select * from Customers ")}
{SELECT_EMPTYROWSET("select * from Customers where 0 = 1")}

[COLUMN:]

This section is a list of all columns found on the specified table or a result from the default query. It contains all the information commonly reported from IColumnsInfo, such as type information, precision, scale, and other info flags to be used when creating and verify data.

[COLUMN] {ColName(iOrdinal, TYPE, ulColumnSize, bPrecision, bScale, dwFlags)} 
{CustomerID(1,DBTYPE_STR ,5,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}

[DATA:]

This section is a list of all data found on the specified table or a result from the default query. The format is a 1:1 correspondence to the column section above. The first row of data is for the first row, and the first column refers to the first column in the Column section. All data is represented in the file in {“String”} format, and NULL is represented as {(null)}. When the testing framework reads this file back in, all types will get converted back into the correct type indicated in the Column section. When the column is of type VARIANT the data value is also prefixed with the VT_TYPE indicator for the specified subtype. To represent a VARIANT with subtype VT_I4 and Value 3, TableDump will produce VT_I4(“3), and DBTYPE_VARIANT will be indicated in the Column section. This is for providers that support VARIANT types, or support the possibility of every VARIANT in different rows to be of a different subtype.

 [DATA] {<Type>("data")} 
{("ALFKI")},{("Alfreds Futterkiste")},{("Maria Anders")},{("Sales Representative")},{("Obere Str. 57")},{("Berlin")},{(null)},{("12209")},{("Germany")},{("030-0074321")},{("030-0076545")},

Example

Suppose you want to test a provider using the OLE DB conformance tests, and need to generate an .ini file that will be used by all the tests.

Here is the example provider information:

ProvderName: MSDASQL

DataSource: OLE_DB_NWind_Jet

UserID: admin

Password:

Table: Customers

DefaultQuery: select * from Customers

The following information is what’s needed to generate the .ini file :

TableDump.exe PROVIDER=MSDASQL; DATASOURCE= OLE_DB_NWind_Jet; USERID=admin; PASSWORD=; TABLENAME=Customers; DEFAULTQUERY=select * from Customers; OUTPUT=Customers.ini;

This will create the following file, Customers.ini:

[INFO] {Provider (Table, <DefaultQuery>)}
{ PROVIDER=MSDASQL (TABLE=Customers, DEFAULTQUERY="select * from Customers")}

[QUERY] {SQLEnumIdentifier("Query")}
{SELECT_ALLFROMTBL("select * from Customers")}
{SELECT_SEARCHABLE("select * from Customers")}
{SELECT_UPDATEABLE("select * from Customers")}
{SELECT_ABCANDCOLLIST("select * from Customers")}
{SELECT_DISTINCTCOLLISTORDERBY("select * from Customers")}
{SELECT_REVCOLLIST("select * from Customers")}
{SELECT_COLLISTGROUPBY("select * from Customers")}
{SELECT_COLLISTWHERELASTCOLINSELECT("select * from Customers")}
{SELECT_REVCOLLISTFROMVIEW("select * from Customers")}
{SELECT_COUNT("select * from Customers")}
{SELECT_COLLISTSELECTREVCOLLIST("select * from Customers")}
{SELECT_EMPTYROWSET("select * from Customers")}
{SELECT_COLLISTFROMTBL("select * from Customers")}
{SELECT_COLLISTTBLUNIONTBL("select * from Customers")}
{SELECT_COLLISTORDERBYCOLONECOMPUTE("select * from Customers")}
{SELECT_CROSSPRODUCT("select * from Customers")}
{SELECT_LEFTOUTERJOIN("select * from Customers")}
{SELECT_RIGHTOUTERJOIN("select * from Customers")}
{SELECT_FROMTBLWITHPARAMS("select * from Customers")}
{SELECT_CHANGECOLNAME("select * from Customers")}
{SELECT_DUPLICATECOLUMNS("select * from Customers")}
{SELECT_REVERSEDUPLICATECOLUMNS("select * from Customers")}
{SELECT_MAXCOLINQUERY("select * from Customers")}
{SELECT_COMPUTEDCOLLIST("select * from Customers")}
{SELECT_UPDATEABLEALLROWS("select * from Customers")}
{SELECT_ORDERBYNUMERIC("select * from Customers")}
{INSERT_1ROW("select * from Customers")}
{INSERT_ALLWITHPARAMS("select * from Customers")}
{SELECT_ALL_WITH_SEARCHABLE_AND_UPDATEABLE("select * from Customers")}
{SELECT_ALL_WITH_BLOB_AT_END("select * from Customers")}
{NO_QUERY("select * from Customers")}
{SELECT_ALL_WITH_FOR_BROWSE("select * from Customers")}

[COLUMN] {ColName(iOrdinal, TYPE, ulColumnSize, bPrecision, bScale, dwFlags)} 
{CustomerID(1,DBTYPE_STR ,5,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{CompanyName(2,DBTYPE_STR ,40,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{ContactName(3,DBTYPE_STR ,30,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{ContactTitle(4,DBTYPE_STR ,30,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{Address(5,DBTYPE_STR ,60,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{City(6,DBTYPE_STR ,15,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{Region(7,DBTYPE_STR ,15,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{PostalCode(8,DBTYPE_STR ,10,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{Country(9,DBTYPE_STR ,15,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{Phone(10,DBTYPE_STR ,24,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}
{Fax(11,DBTYPE_STR ,24,255,255,DBCOLUMNFLAGS_WRITE | DBCOLUMNFLAGS_ISNULLABLE | DBCOLUMNFLAGS_MAYBENULL)}

[DATA] {<Type>("data")} 
{("ALFKI")},{("Alfreds Futterkiste")},{("Maria Anders")},{("Sales Representative")},{("Obere Str. 57")},{("Berlin")},{(null)},{("12209")},{("Germany")},{("030-0074321")},{("030-0076545")},
{("ANATR")},{("Ana Trujillo Emparedados y helados")},{("Ana Trujillo")},{("Owner")},{("Avda. de la Constitución 2222")},{("México D.F.")},{(null)},{("05021")},{("Mexico")},{("(5) 555-4729")},{("(5) 555-3745")},
{("ANTON")},{("Antonio Moreno Taquería")},{("Antonio Moreno")},{("Owner")},{("Mataderos 2312")},{("México D.F.")},{(null)},{("05023")},{("Mexico")},{("(5) 555-3932")},{(null)},
{("AROUT")},{("Around the Horn")},{("Thomas Hardy")},{("Sales Representative")},{("120 Hanover Sq.")},{("London")},{(null)},{("WA1 1DP")},{("UK")},{("(171) 555-7788")},{("(171) 555-6750")},
{("BERGS")},{("Berglunds snabbköp")},{("Christina Berglund")},{("Order Administrator")},{("Berguvsvägen 8")},{("Luleå")},{(null)},{("S-958 22")},{("Sweden")},{("0921-12 34 65")},{("0921-12 34 67")},
{("BLAUS")},{("Blauer See Delikatessen")},{("Hanna Moos")},{("Sales Representative")},{("Forsterstr. 57")},{("Mannheim")},{(null)},{("68306")},{("Germany")},{("0621-08460")},{("0621-08924")},
{("BLONP")},{("Blondel père et fils")},{("Frédérique Citeaux")},{("Marketing Manager")},{("24, place Kléber")},{("Strasbourg")},{(null)},{("67000")},{("France")},{("88.60.15.31")},{("88.60.15.32")},
{("BOLID")},{("Bólido Comidas preparadas")},{("Martín Sommer")},{("Owner")},{("C/ Araquil, 67")},{("Madrid")},{(null)},{("28023")},{("Spain")},{("(91) 555 22 82")},{("(91) 555 91 99")},
{("BONAP")},{("Bon app'")},{("Laurence Lebihan")},{("Owner")},{("12, rue des Bouchers")},{("Marseille")},{(null)},{("13008")},{("France")},{("91.24.45.40")},{("91.24.45.41")},
{("BOTTM")},{("Bottom-Dollar Markets")},{("Elizabeth Lincoln")},{("Accounting Manager")},{("23 Tsawassen Blvd.")},{("Tsawassen")},{("BC")},{("T2F 8M4")},{("Canada")},{("(604) 555-4729")},{("(604) 555-3745")},
{("BSBEV")},{("B's Beverages")},{("Victoria Ashworth")},{("Sales Representative")},{("Fauntleroy Circus")},{("London")},{(null)},{("EC2 5NT")},{("UK")},{("(171) 555-1212")},{(null)},

*The rest is removed for simplicity and saving trees…

Section 4: Building and Running the ADO Minimal Tests

ADO Level 0 Conformance Tests

The mapping of ADO properties and methods to OLE DB interfaces provides the basis for the grouping of ADO properties and methods into the conformance levels.

Before running ADO Level O conformance tests, you must manually modify the .ini file generated by TableDump. (See example in the previous section, “Example.”) Modify the SELECT_EMPTYROWSET line under [QUERY] by adding a query that will yield no results. For example:

{SELECT_EMPTYROWSET("select * from mytable where 1=2")}

If you do not modify this line, end-of-file and beginning-of-file tests will fail.

ADO Update Conformance Tests

These tests are provided to confirm that ADO Update statements will work with compliant updatable providers.

ADO Transaction Conformance Tests

These tests are provided to confirm that ADO Transaction statements will work with compliant providers that support transactions.

Building ADOPriv.dll

Before running the ADO tests, you must build ADOPriv.dll.

  1. To build ADOPriv.dll, use Open Workspace on the InstallDirectory\ Conformance\Tools\ADOPriv\ADOPriv.dsp in Visual C++®.

  2. Add all the include directories and all the LIB directories for the version 2.0 SDK to your Visual C++ directory. (To do this in Visual C++, on the Tools menu, click Options, and then click Directories.)

  3. Update your system path to include the following directories:

    InstallDirectory\Conformance\Tests\Proposed\OLEDBTests\Include

    InstallDirectory\Conformance\Include

    InstallDirectory\Conformance\Lib

  4. Build ADOPriv using the default target.

  5. Copy ADOPriv.dll to

    InstallDirectory\Conformance\Lib

  6. Register it in that directory using Regsrv32.exe

Getting Started

The ADO tests are in

InstallDirectory\Conformance\Tests\Proposed\ADOTests

The test .dll and .reg files are in the ADOTests subdirectory itself. The source is in the SRC subdirectory, in case you need to rebuild the tests.

ADOPriv.dll is in the Tools subdirectory. (This is the wrapper for the PrivLib used by the ADO tests for common functionality.)

  1. Register the ADO tests by executing regsvr32 on each of the ADO test .dll files. For example:
    regsvr32 adolvl0.dll

  1. Execute each of the .reg files. For example: adolvl0.reg.

  2. If you haven’t already done so, create an .ini file using the TableDump program found in the Tools subdirectory.

  3. Start LTM by executing LTM.exe. When LTM is running, set up a provider by adding a new provider, which means specifying the connection string. See the next section for more information on creating a provider connection string.

  4. Click the test module, click the provider you added, and then click Run.

Test modules and LTM are set up so you can run a test module, a test case, or a test variation.

  1. Click the plus sign next to the test module to expose the cases in that module. Click the plus sign next to a test case to expose the variations in that case.

Each variation tests a single test scenario. Each variation will return pass or failure. In many cases, the variation will also return the expected HRESULT and the actual HRESULT received.

Provider Connection String

ODBC Provider Example:

DATASOURCE=ADOT7;
USERID=adolab;
PASSWORD=sometext;
FILE=C:\testdrop\ wayl7.ini;
DefaultQuery=select * from wayl7;
CURSORLOC=client;CONNECTIONTIMEOUT=500;

Oracle Provider Example:

DATASOURCE=goliath.world;
USERID=ADOLAB1;
PASSWORD=sometext;
FILE=C:\testdrop\ wayl7can.ini;
DefaultQuery=select * from wayl7;
CURSORLOC=server;

Debugging

Your provider should get zero failures when running the Level 0 tests. If it supports updates and transactions, it should also get zero failures when running the Updatability and Transaction tests.

In case there is a failure, the ADO tests can be viewed and stepped through by using Visual Studio™. Simply launch LTM, launch Visual Studio, attach to the TD process, and open the desired Visual Basic® source file.

It is not possible at this time to debug the ADO tests in the Visual Basic environment